package br.com.pi.SmartFast.controler;

import br.com.pi.SmartFast.model.Mesa;
import br.com.pi.SmartFast.model.Pedidos;
import br.com.pi.SmartFast.model.PedidosDAO;
import br.com.pi.SmartFast.model.Produto;
import br.com.pi.SmartFast.model.ProdutoDAO;
import br.com.pi.SmartFast.model.TipoProduto;
import java.awt.Image;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;


/**
 *
 * @author Alessandro
 */
public class ControleCozinha implements Runnable {

    private JList list_pratos, list_sobremesas;
    private DefaultListModel model_prato = new DefaultListModel();
    private DefaultListModel model_sobremesa = new DefaultListModel();
    private JFrame tela_cozinha;
    private JButton bt_sair;
    private JLabel foto_produto;
    private ProdutoDAO dao = new ProdutoDAO();
    private JDialog dial_pedidos;
    private JTree arvore_produtos_pedidos;

    public ControleCozinha(JList list_pratos, JList list_sobremesas,
            JTree arvore, JFrame tela_cozinha, JButton bt_sair, JDialog dial_pedidos,
            JLabel foto) {
        this.list_pratos = list_pratos;
        this.list_sobremesas = list_sobremesas;
        this.arvore_produtos_pedidos = arvore;
        this.tela_cozinha = tela_cozinha;
        this.bt_sair = bt_sair;
        this.dial_pedidos = dial_pedidos;
        this.foto_produto = foto;
    }

    /**Use este método para inicialização da tela cozinha
     * 
     */
    @SuppressWarnings("static-access")
    public void aoAbrirTelaCozinha() {

        this.tela_cozinha.setExtendedState(JFrame.MAXIMIZED_BOTH);//maximiza a tela
        Thread t1 = new Thread(this);//cria um objeto do tipo thread
        t1.start();//inicia o ciclo
        t1.setPriority(10);//prioriza no máximo a execução do objeto no processador

    }

    /** Método run da interface runnable. Está sendo sobreescrito para a consulta no
     * banco de dados, retornando as mesas que estão com pedidos em aberto
     */
    @Override
    public void run() {
        try {
            while (true) {//enquanto verdadeiro
                this.getMesasPratosSobremesas();//chama o método de consulta no banco
                Thread.sleep(30000);//concede um intervalo de 30' ao processador
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, "Erro ao consultar Dados no Banco", "Consulta Banco Dados", JOptionPane.ERROR);

        }
    }

    /**Método para consulta de mesas que devem ser atendidas com
     * pratos ou sobremesas
     * @throws SQLException
     */
    private void getMesasPratosSobremesas() throws SQLException {

        //SELECIONA MESAS COM PEDIDOS DE PRATOS
        String sql = "select distinct pd.fk_mesa as mesa"
                + " from pedidos as pd, produtos as prod"
                + " where pd.ped_atendido is false and "
                + " prod.fk_tipo_produto = 1 and"
                + " pd.fk_produtos = prod.id_produtos and" +
                " pd.prod_pago is false"
                + " order by pd.data_hora ";



        this.model_prato.clear();//limpa as listas
        this.list_pratos.removeAll();

        ResultSet rs = dao.getDadosTabela(sql);//recebe a consulta sql
        if (rs.next()) {//se existirem registros
            do {
                model_prato.addElement(" MESA : " + rs.getInt("mesa"));//modelo recebe nº mesa
            } while (rs.next());
            this.list_pratos.setModel(model_prato);//lista recebe o modelo de informações
            rs.close();//fecha a consulta
        } else {
        }

        //SELECIONA PEDIDOS DE SOBREMESAS
        sql = "select distinct pd.fk_mesa as mesa"
                + " from pedidos as pd, produtos as prod"
                + " where pd.ped_atendido is false and "
                + " prod.fk_tipo_produto = 2 and"
                + " pd.fk_produtos = prod.id_produtos and" +
                " pd.prod_pago is false"
                + " order by pd.data_hora ";

        this.model_sobremesa.clear();//mesmo procedimento acima
        this.list_sobremesas.removeAll();

        rs = dao.getDadosTabela(sql);
        if (rs.next()) {
            do {
                model_sobremesa.addElement(" MESA : " + rs.getInt("mesa"));
            } while (rs.next());
            this.list_sobremesas.setModel(model_sobremesa);
            rs.close();
        } else {
        }


    }

    /** Usar este método para quando o usuario clicar no list pratos
     * Habilita a tela de diálogo com a descrição de pedidos
     * @param clique
     */
    public void ListaPratosAoClicar(int clique, int lista) {

        try {
            if (clique == 2 && lista == 1) {//se o usuario clicar 2 vezes...

                this.dial_pedidos.setBounds(120, 120, 800, 600);//dimensiona a tela
                this.dial_pedidos.setVisible(true);//Tela fica visível
                this.getRelacaoProdutosPedidos(lista);//Método retorna pratos/sobremesas para determinada mesa

            } else {
                if (clique == 2 && lista == 2) {//se o usuario clicar 2 vezes...

                    this.dial_pedidos.setBounds(120, 120, 800, 600);//dimensiona a tela
                    this.dial_pedidos.setVisible(true);//Tela fica visível
                    this.getRelacaoProdutosPedidos(lista);//Método retorna pratos/sobremesas para determinada mesa
                }
            }
        } catch (Exception e) {//trata erro
            JOptionPane.showMessageDialog(null, "Sem Conexão com Banco de Dados!!!");

        }

    }

    /** Retorna o número da mesa selecionada pelo cliente
     *
     * @return
     */
    private int getNumeroMesa(int lista) {

        int n_mesa = 0;
        //Se existir alguma mesa selecionada
        if (this.list_pratos.isSelectedIndex(this.list_pratos.getSelectedIndex()) && lista == 1) {
            //mesa recebe o número da mesa selecionada
            String mesa = this.list_pratos.getSelectedValue().toString().substring(8);
            n_mesa = Integer.parseInt(mesa);//converte String para inteiros

        } else {//mesmo procedimento

            if (this.list_sobremesas.isSelectedIndex(this.list_sobremesas.getSelectedIndex()) && lista == 2) {
                String mesa = this.list_sobremesas.getSelectedValue().toString().substring(8);
                n_mesa = Integer.parseInt(mesa);

            }

        }
        return n_mesa;//retorna o número  da mesa

    }

    /** Retorna a relação de produtos pedidos pela mesa
     *
     * @throws SQLException
     */
    private void getRelacaoProdutosPedidos(int lista) throws SQLException {

        String produto = "";//nome do produto
        DefaultMutableTreeNode tronco = null;//tronco da arvore
        DefaultMutableTreeNode galho = null;//galhos do tronco
        this.arvore_produtos_pedidos.setModel(null);//inicializa o JTree

        //consulta sql para retornar quantidade e produto com base em uma mesa
        String sql = "select ped.quantidade_prod as quant , prod.nome as nome, prod.id_produtos as id"
                + " from produtos as prod, pedidos as ped"
                + " where ped.fk_mesa = " + this.getNumeroMesa(lista) + " and" +
                " ped.ped_atendido is false and"
                + " prod.id_produtos = ped.fk_produtos and" +
                " prod.fk_tipo_produto =" + lista;

//declaro a raiz da árvore
        DefaultMutableTreeNode raiz = new DefaultMutableTreeNode("Pedidos");

        ResultSet rs = this.dao.getDadosTabela(sql);//rs recebe a consulta do banco

        if (rs.next()) {//se existir informações
            do {
                produto = rs.getString("nome");//variavel recebe o nome do produto pedido
                //tronco da árvore recebe a quant. produto e o nome do mesmo
                tronco = new DefaultMutableTreeNode(rs.getInt("quant") + "  " + rs.getString("nome") + " /" + rs.getInt("id"));
                //pesquiso no banco pelos itens do produto
                ResultSet rsi = this.dao.getDadosTabela("select it.nome as item"
                        + " from itens as it, itens_produto as ip, produtos as pd"
                        + " where pd.nome like '" + produto + "' and "
                        + " it.id_itens = ip.fk_id_itens and"
                        + " ip.fk_id_produtos = pd.id_produtos ");
                if (rsi.next()) {//se existirem itens cadastrados
                    do {
                        // galhos do tronco recebem os itens do produto
                        galho = new DefaultMutableTreeNode(rsi.getString("item"));
                        //tronco adiciona os galhos criados
                        tronco.add(galho);
                    } while (rsi.next());//encerra o laço de itens
                }
                rsi.close();//fecha a consulta de itens
                raiz.add(tronco);//raiz adiciona o tornco com seus galhos
            } while (rs.next());//encerra o laço de produtos
        }
        if (!rs.isClosed()) {
            rs.close();//fecha a consulta de produtos
        }
        //Estou criando um modelo de árvore para inserir no JScrollPane da tela
        DefaultTreeModel modelo = new DefaultTreeModel(raiz);
        //Árvore insere o modelo com as informações ganhas na consulta ao banco
        this.arvore_produtos_pedidos.setModel(modelo);

    }

    /** Desabilita a tela de produtos da mesa
     *
     */
    public void botaoSairTelaProdutosMesa() {
        this.dial_pedidos.setVisible(false);
    }

    /**Botão de prato atendido com métodos para trata-lo
     *
     */
    public void BotaoPratoEntregueAoClicar(int lista) {

        try {
            //Verifica se possui alguma mesa selecionada para informar que esta foi atendida
            if (!this.list_pratos.isSelectionEmpty() || !this.list_sobremesas.isSelectionEmpty()) {
                this.setPedidoAtendido(lista);//método que informa que a mesa foi atendida
                this.getMesasPratosSobremesas();//método que pesquisa no banco por mesas a serem atendidas
            } else {
                JOptionPane.showMessageDialog(null, "Escolha uma mesa !!");//mensagem de erro
            }

        } catch (Exception e) {//tratamento de erro
            
        }
    }

    /**Método destinado a informar que determinada mesa recebeu atendimento
     *
     */
    private void setPedidoAtendido(int lista) {


        Pedidos pd = new Pedidos();//objeto pedidos
        Mesa ms = new Mesa();//objeto mesa
        PedidosDAO pdd = new PedidosDAO();//objeto pedidos dao (banco de dados)
        Produto prod = new Produto();
        TipoProduto tp = new TipoProduto();

        if(lista == 1){
            tp.setCodigo_tipo(1);
            prod.setTipo_produto(tp);
        }else{
            if(lista == 2){
                tp.setCodigo_tipo(2);
                prod.setTipo_produto(tp);
            }
        }


        int num_mesa = this.getNumeroMesa(lista);// num_mesa recebe o número da mesa
        ms.setCod_mesa(num_mesa);//objeto ms recebe o número da mesa
        

        pd.setMesa(ms);//objeto pedido associa objeto mesa
        pd.setPed_atendido(true);//objeto pedido recebe informação de mesa atendida
        pd.setProduto(prod);
        

        pdd.EditarPedidos(pd);//método para editar no banco de dados


    }

    /**Método para interagir com usuário na JTree da tela\
     * 
     * @param clique
     */
    public void jTreeArvoreAoClicar(int clique) {
        try {
            if (clique == 2) {
                this.getRetornaImagemProduto();
            }

        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Erro ao Acessar Banco de Dados!!");
            System.out.println(e);
        }
    }

    /**Método para inserir imagem do produto em label na tela produtos / itens
     *
     * @throws SQLException
     */
    private void getRetornaImagemProduto() throws SQLException {

        //resgata da tela o nome do produto com seu código no banco  de dados
        String produto = this.arvore_produtos_pedidos.getAnchorSelectionPath().getLastPathComponent().toString();

        Integer cod = this.getCodigoProduto(produto);

        if (cod != null) {
            StringBuilder sb = new StringBuilder("select foto from produtos where id_produtos = " + cod);
            ResultSet rs = this.dao.getDadosTabela(sb.toString());

            if (rs.next()) {
                if (rs.getBytes("foto") != null) {
                    Image img = new ImageIcon(rs.getBytes("Foto")).getImage();
                    this.foto_produto.setIcon(new ImageIcon(img));

                }
            }
        } else {
            this.foto_produto.setIcon(new ImageIcon("src/br/com/pi/SmartFast/imagens/imgCozinha.png"));
        }
    }

    /**Método próprio a retornar o código do produto em uma relação quant/produto de uma lista
     * de produtos a serem atendidos
     * @param texto
     * @return
     */
    private Integer getCodigoProduto(String texto) {

        if (texto.contains("/")) {
            String[] cod = texto.split("/");
            return Integer.parseInt(cod[1]);
        } else {
            return null;
        }



    }
}
